from copy import deepcopy
import logging, time

# 备忘模式中主要有三个角色：发起人（需要进行备份的对象）、备忘录（备份的状态，即一个备份的文档）、备忘录管理者（备份文档的管理者，由他负责人与发起人的交互）
class Memento:
    """备忘录"""
    def __init__(self):
        self.__cmdName = ""
        self.__cmdArgs = []

    def setAttributes(self, _dict):
        """深度拷贝字典dict中的所有属性"""
        self.__dict__ = deepcopy(_dict)

    def getAttributes(self):
        """获取属性字典"""
        return self.__dict__

    def __str__(self):
        return self.__cmdName + " " + " ".join(self.__cmdArgs)


class Caretaker:
    """备忘录管理类"""
    def __init__(self):
        self._mementos = {}

    def addMemento(self, memento):
        name = time.strftime("%Y-%m-%d %H:%M:%S" ,time.localtime())
        self._mementos[name] = memento

    def getMemento(self, name):
        return self._mementos[name]


class Originator:
    """备份发起人"""
    def createMemento(self):
        memento = Memento()
        memento.setAttributes(self.__dict__)
        return memento

    def restoreFromMemento(self, memento):
        self.__dict__.update(memento.getAttributes())


# Doc历史指令存储
class TerminalCmd(Originator):
    """终端命令"""
    def __init__(self, text):
        self.__cmdName = ""
        self.__cmdArgs = []
        self.parseCmd(text)

    def parseCmd(self, text):
        """从字符串中解析命令"""
        subStrs = self.getArgumentsFromString(text, " ")
        # 获取第一个字段作为命令的名称
        if len(subStrs) > 0:
            self.__cmdName = subStrs[0]

        if len(subStrs) > 0:
            self.__cmdArgs = subStrs[1:]

    def getArgumentsFromString(self, _str, splitFlag):
        """通过splitFlag进行分割，获得参数数组"""
        if splitFlag == "":
            logging.warning("splitFlag为空！")
            return ""
        data = str.split(splitFlag)
        result = []
        for item in data:
            item.strip()
            if item != "":
                result.append(item)
        return result

    def showCmd(self):
        print(self.__cmdName, self.__cmdArgs)

    
class TerminalCaretaker(Caretaker):
    """终端命令的备忘录管理器"""
    def showHistory(self):
        """显示历史命令"""
        for key, memento in self._mementos:
            print(key + ":" + Memento)


def testTerminal():
    caretaker = TerminalCaretaker()
    curCmd = TerminalCmd("")
    while True:
        strCmd = input("请输入指令:")
        strCmd = strCmd.lower()
        if strCmd.startswith("q"):
            exit(0)
        elif strCmd.startswith("h"):
            caretaker.showHistory()
        elif strCmd.startswith("!"):
            idx = strCmd[1]
            curCmd.restoreFromMemento(caretaker.getMemento(idx))
            curCmd.showCmd()
        else:
            curCmd = TerminalCmd(strCmd)
            curCmd.showCmd()
            caretaker.addMemento(curCmd.createMemento())


testTerminal()
